/*
 * Copyright (C) 2022-2024 Huawei Device Co., Ltd.
 * Licensed under the MIT License, (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { References } from './References';
import HashMap from '@ohos.util.HashMap';
import ArrayList from '@ohos.util.ArrayList';
import { ListenerInfo } from '../entry/ListenerInfo';
import { Utils } from '../utils/Utils';
import { HandlerOptions } from './Handler';
import { MetadataReader } from './MetadataReader';

export namespace Annotations {
    const methodMap: HashMap<String | symbol, ArrayList<ListenerInfo>> = new HashMap<String | symbol, ArrayList<ListenerInfo>>();

    export function noticeHandleListener(msg: Object, methodName: String, listener) {
        var className = Utils.getClassName(listener);
        if (methodMap.hasKey(className)) {
            var methodArray = methodMap.get(className);
            methodArray.forEach((value, index) => {
                if (value.getMethodName() == methodName) {
                    value.getMethodFun()(msg, listener);
                    return;
                }
            })
        }
    }

    export function handle(handler?: HandlerOptions): MethodDecorator {
        return function (target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
            var className = Utils.getClassName(target);
            var methodList: ArrayList<ListenerInfo>;
            if (methodMap.hasKey(className)) {
                methodList = methodMap.get(className);
            }
            if (!methodList) {
                methodList = new ArrayList<ListenerInfo>();
            }
            const sourceMethod = descriptor.value;

            descriptor.value = async function (...args: any) {
                await sourceMethod.apply(this, args);
            }
            var listener = new ListenerInfo();
            listener.setClassName(className);
            listener.setMethod(JSON.stringify(propertyKey), descriptor.value);
            methodList.add(listener);
            methodMap.set(className, methodList);
            MetadataReader.getInstance().setSubHandle(className, JSON.stringify(propertyKey), handler); //保存listener的方法注解的值
        }
    }


    export function Listener(className: String, reference: References): ClassDecorator {
        MetadataReader.getInstance().setListenerReferencesType(className, reference);
        return (target: any) => {
            var className = Utils.getClassName(target);
        }
    }
}